import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from matplotlib.colors import LinearSegmentedColormap
import matplotlib.patches as patches
import os

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号


def load_erp_data():
    """加载ERP订单数据"""
    try:
        # 读取之前生成的ERP数据
        data_path = r"D:\大三上\大数据分析及数据可视化\《Excel数据可视化 - 从图表到数据大屏》-清华-郭宏远\实验\erp_order_data.xlsx"
        df = pd.read_excel(data_path)
        return df
    except Exception as e:
        print(f"数据加载失败: {e}")
        # 如果数据不存在，创建示例数据
        return create_sample_data()


def create_sample_data():
    """创建示例数据（备用）"""
    regions = ['华北', '华南', '东北', '西北', '西南', '华东']
    sales = [2354, 1902, 3524, 2698, 2896, 2563]
    return pd.DataFrame({'province': regions, 'product_amount': sales})


def create_gradient_barchart_with_erp_data():
    """基于ERP数据创建渐变柱形图"""
    # 加载数据
    df = load_erp_data()

    # 按省份汇总销售金额
    sales_by_region = df.groupby('province')['product_amount'].sum().sort_values(ascending=False)

    # 准备图表数据
    regions = sales_by_region.index.tolist()
    sales = sales_by_region.values.tolist()

    # 创建图形和坐标轴 - 设置靛蓝色背景
    fig = plt.figure(figsize=(14, 9), facecolor='#1A1A2E')
    ax = fig.add_subplot(111, facecolor='#1A1A2E')

    # 创建渐变颜色映射（从深蓝到浅蓝）
    colors = ['#16213E', '#0F3460', '#1A5F7A', '#2C8C99', '#4BB5C2', '#7FD6E3']
    cmap = LinearSegmentedColormap.from_list('ocean_blue', colors, N=100)

    # 绘制柱形图
    bar_width = 0.7
    x_pos = np.arange(len(regions))

    # 先绘制基础柱子
    bars = ax.bar(x_pos, sales, width=bar_width,
                  color='#2C8C99', edgecolor='#E0E0E0', linewidth=2, alpha=0.3)

    # 为每个柱子手动创建渐变效果
    for i, (x, sale) in enumerate(zip(x_pos, sales)):
        gradient_height = 80  # 渐变分段数量
        for j in range(gradient_height):
            height_segment = sale / gradient_height
            y_bottom = j * height_segment
            y_top = (j + 1) * height_segment

            # 计算当前段的颜色（从深到浅）
            color_ratio = 1 - (j / gradient_height) * 0.7
            color = cmap(color_ratio)

            # 绘制渐变段
            rect = patches.Rectangle(
                (x - bar_width / 2, y_bottom), bar_width, height_segment,
                linewidth=0, facecolor=color, alpha=0.9
            )
            ax.add_patch(rect)

    # 添加白色边框
    for i, bar in enumerate(bars):
        bar.set_edgecolor('#E0E0E0')
        bar.set_linewidth(2)

    # 设置图表样式 - 使用浅色文字
    # 标题
    ax.set_title('各地区销售金额对比分析\n渐变柱形图',
                 fontsize=20, fontweight='bold', pad=25, color='#FFFFFF') # 调大字号，加粗
    # Y轴标签
    ax.set_ylabel('销售金额 (元)', fontsize=18, fontweight='bold', color='#E0E0E0') # 调大字号，加粗
    # X轴标签
    ax.set_xlabel('地区', fontsize=16, fontweight='bold', color='#E0E0E0') # 调大字号，加粗

    # 设置坐标轴
    ax.set_xticks(x_pos)
    ax.set_xticklabels(regions, fontsize=14, fontweight='bold', color='#E0E0E0') # 调大字号，加粗
    ax.tick_params(axis='y', labelsize=14, colors='#E0E0E0') # 调大字号

    # 美化坐标轴
    for spine in ax.spines.values():
        spine.set_color('#4A4A6A')
        spine.set_linewidth(2)

    # 设置网格线
    ax.grid(axis='y', alpha=0.3, linestyle='--', color='#4A4A6A')
    ax.set_axisbelow(True)

    # 在柱子顶部显示数值 - 修正数据标签样式
    for i, v in enumerate(sales):
        # 使用 bbox 参数创建一个圆角矩形背景，模仿Excel样式
        # 关键点：设置 facecolor 为比背景稍亮一点的深色，边缘透明或无边框
        ax.text(i, v + max(sales) * 0.03, f'{v:,}', ha='center', va='bottom',
                fontsize=14, fontweight='bold', color='#FFFFFF', # 调大字号，加粗
                # 这里是关键！修改 bbox 参数
                bbox=dict(boxstyle='round,pad=0.3', # 圆角矩形，增加内边距
                          facecolor='#2C3E50', # 背景色，使用一个比主背景稍亮的深色
                          edgecolor='none', # 无边框！这是去除“方框”的关键
                          alpha=0.7)) # 降低不透明度，使其更融入背景

    # 设置y轴范围
    ax.set_ylim(0, max(sales) * 1.15)

    # 添加数据来源文本
    ax.text(0.02, 0.98, '数据来源：ERP订单系统', transform=ax.transAxes,
            fontsize=12, color='#B0B0B0', alpha=0.7, va='top')

    # 添加装饰性元素
    ax.text(0.98, 0.02, '可视化分析', transform=ax.transAxes,
            fontsize=12, color='#B0B0B0', alpha=0.5, ha='right',
            style='italic')

    # 调整布局
    plt.tight_layout()

    # 确保输出目录存在
    output_dir = r"D:\大三上\大数据分析及数据可视化\《Excel数据可视化 - 从图表到数据大屏》-清华-郭宏远\实验\results"
    os.makedirs(output_dir, exist_ok=True)

    # 保存高质量图片
    output_path = os.path.join(output_dir, '01_渐变柱形图.png')
    plt.savefig(output_path, dpi=300, bbox_inches='tight',
                facecolor='#1A1A2E', edgecolor='none')

    plt.show()

    # 打印数据分析
    print("=" * 60)
    print("渐变柱形图数据分析报告")
    print("=" * 60)
    print(f"数据统计期间：ERP订单数据")
    print(f"数据总量：{len(df)}条订单记录")
    print(f"汇总地区数：{len(regions)}个地区")
    print(f"总销售金额：¥{sum(sales):,.0f}")
    print(f"平均地区销售：¥{np.mean(sales):,.0f}")
    print(f"最高销售地区：{regions[0]} - ¥{sales[0]:,.0f}")
    print(f"最低销售地区：{regions[-1]} - ¥{sales[-1]:,.0f}")
    print(f"销售标准差：¥{np.std(sales):,.0f}")

    print("\n地区销售排名：")
    print("-" * 40)
    for rank, (region, sale) in enumerate(zip(regions, sales), 1):
        percentage = (sale / sum(sales)) * 100
        print(f"第{rank:2d}名：{region} - ¥{sale:>8,.0f} ({percentage:5.1f}%)")

    print(f"\n图表已保存至：{output_path}")

    return fig, ax, df


# 创建图表
if __name__ == "__main__":
    print("开始生成基于ERP数据的渐变柱形图...")

    # 创建主版本
    print("生成主版本渐变柱形图...")
    fig, ax, df = create_gradient_barchart_with_erp_data()

    print("\n" + "=" * 60)
    print("图表生成完成！")
    print("=" * 60)
    print("已保存文件：")
    print("✓ 01_渐变柱形图.png")
    print(f"\n数据统计：")
    print(f"- 总订单数：{len(df)}")
    print(f"- 涉及地区：{df['province'].nunique()}个")
    print(f"- 总销售金额：¥{df['product_amount'].sum():,.0f}")